package gengine.common.misc;

import gengine.common.packets.BasePacket;
import gengine.common.packets.PacketParsingException;

import java.io.*;
import java.net.Socket;

/**
 * User: arseniy
 * Date: 20.12.11
 */
public abstract class BaseClientThread extends Thread {
    private Socket socket;
    protected int id;
    private boolean interrupt;
    private ObjectOutputStream outputStream;
    private ObjectInputStream inputStream;


    public BaseClientThread(Socket socket, int id) throws IOException {
        this.socket = socket;
        this.id = id;
        outputStream = new ObjectOutputStream(socket.getOutputStream());
    }

    @Override
    public void run() {
        BaseApplication.log("ClientThread thread started",LogCategory.Info);
        try {
            inputStream =  new ObjectInputStream(socket.getInputStream());
            while (!interrupt) {

                BasePacket bp = BasePacket.read(inputStream);
                BaseApplication.log("Object was read",LogCategory.Debug);
                ProcessPacket(bp);

            }
        } catch (PacketParsingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BaseApplication.log("ClientThread thread closed",LogCategory.Info);
    }

    @Override
    public void interrupt() {
        interrupt=true;
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        super.interrupt();
    }

    public int getClientId() {return id;}

    protected abstract void ProcessPacket(BasePacket packet);

    public boolean sendPacketImmediately(BasePacket packet) {
        if (!isConnected())
            return false;
        try {
            packet.setClientId(id);
            packet.write(outputStream);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean isConnected() {
        return socket.isConnected() && !socket.isClosed() && super.isAlive();
    }
}
